package com.gitee.wsl.ext.string

internal fun String.isComment() = this.trim().startsWith("#")

fun String.parseSlotScope(): Map<String, String> {
    if (isEmpty()) return emptyMap()
    var str = this
    if (startsWith("{") && endsWith("}")) str = str.substring(1, str.length - 1)
    return str.parseStringMap(':', ',')
}

fun String.parseStringMap(keySepChar: Char, itemSepChar: Char): Map<String, String> {
    if (isEmpty()) return emptyMap()

    val list: List<String> = split(itemSepChar)
    if (list.isEmpty()) return emptyMap()

    val ret = LinkedHashMap<String, String>()
    for (item in list) {
        if (item.isBlank()) continue
        val pos = item.indexOf(keySepChar)
        if (pos < 0) {
            val key = item.trim { it <= ' ' }
            ret[key] = key
            continue
        }
        val key = item.substring(0, pos).trim { it <= ' ' }
        val value = item.substring(pos + 1).trim { it <= ' ' }
        ret[key] = value
    }
    return ret
}

/**
 * method for splitting the string to the array: "[[a, b], [c], [d]]" to -> [a,b] [c] [d]
 */
@Suppress("NESTED_BLOCK", "TOO_LONG_FUNCTION")
fun String.parseArray(): MutableList<String> {
    val trimmed = trimBrackets().trim().removeTrailingComma()
    // covering cases when the array is intentionally blank: myArray = []. It should be empty and not contain null
    if (trimmed.isBlank()) {
        return mutableListOf()
    }

    var nbBrackets = 0
    var isInBasicString = false
    var isInLiteralString = false
    var bufferBetweenCommas = StringBuilder()
    val result: MutableList<String> = mutableListOf()

    for (i in trimmed.indices) {
        when (val current = trimmed[i]) {
            '[' -> {
                nbBrackets++
                bufferBetweenCommas.append(current)
            }
            ']' -> {
                nbBrackets--
                bufferBetweenCommas.append(current)
            }
            '\'' -> {
                if (!isInBasicString) {
                    isInLiteralString = !isInLiteralString
                }
                bufferBetweenCommas.append(current)
            }
            '"' -> {
                if (!isInLiteralString) {
                    if (!isInBasicString) {
                        isInBasicString = true
                    } else if (trimmed[i - 1] != '\\') {
                        isInBasicString = false
                    }
                }
                bufferBetweenCommas.append(current)
            }
            // split only if we are on the highest level of brackets (all brackets are closed)
            // and if we're not in a string
            ',' -> if (isInBasicString || isInLiteralString || nbBrackets != 0) {
                bufferBetweenCommas.append(current)
            } else {
                result.add(bufferBetweenCommas.toString())
                bufferBetweenCommas = StringBuilder()
            }
            else -> bufferBetweenCommas.append(current)
        }
    }
    result.add(bufferBetweenCommas.toString())
    return result
}
